import { keywordCompare } from '@gnlab/utils'
import { Button, Input, Tooltip, Checkbox, Tag, message } from 'antd'
import type { CheckboxChangeEvent } from 'antd/lib/checkbox'
import { OrderedSet, OrderedMap } from 'immutable'
import  defaultAvatar  from '@/desktop/assets/avatar.jpg'
import services from '@/services'
import { type InternalContact } from '@/services/contact-types'
import { makeContactId } from '@/services/contacts'
import { type Contact } from '@/services/contacts'

import './ToNewGroup.module.less'

export default function PullInNewGroupContent(props: { contact: Contact; onCancel: () => void }) {
  const { contact, onCancel } = props

  const reducer = useCallback(
    (
      state: {
        search: string
        choosed: OrderedSet<string>
        submitting: boolean
      },
      action:
        | { type: 'start-submit' }
        | { type: 'set-search'; search: string }
        | { type: 'choosed'; id: string }
        | { type: 'cancel-choosed'; id: string },
    ) => {
      switch (action.type) {
        case 'start-submit':
          return { ...state, submitting: true }
        case 'set-search':
          return { ...state, search: action.search }
        case 'choosed':
          return { ...state, choosed: state.choosed.add(action.id) }
        case 'cancel-choosed':
          return { ...state, choosed: state.choosed.delete(action.id) }
        default:
          return state
      }
    },
    [],
  )
  function getInitialState() {
    return {
      search: '',
      choosed: OrderedSet([
        // 初始选中当前联系人对应的员工
        makeContactId(contact.ownerWxid, contact.ownerWxid),
      ]),
      submitting: false,
    }
  }
  const [{ search, choosed, submitting }, dispatch] = useReducer(reducer, null, getInitialState)

  const [allEmployees, setAllEmployees] = useState(OrderedMap<string, InternalContact>())
  useEffect(() => {
    void services.internals
      .request({ wxids: [contact.ownerWxid], page: 1, pageSize: 1000000 })
      .then(res => {
        if (res.success) {
          const employees = res.data
          employees.sort(v => (v.userId === contact.ownerWxid ? -1 : 1)) // 当前联系人所属的员工排最前面
          setAllEmployees(OrderedMap(employees.map(v => [v.id, v])))
        } else {
          void message.warning('员工列表加载失败：' + res.error)
        }
      })
  }, [contact.ownerWxid])

  const employees = useMemo(
    () => allEmployees.filter(ct => !search || keywordCompare(search, ct.name)),
    [search, allEmployees],
  )

  const searchOnChange = (e: React.ChangeEvent<HTMLInputElement>) =>
    dispatch({ type: 'set-search', search: e.target.value })
  const choose = useCallback((id: string, targetChoosed: boolean) => {
    if (targetChoosed) dispatch({ type: 'choosed', id })
    else dispatch({ type: 'cancel-choosed', id })
  }, [])

  const addGroup = useCallback(() => {
    dispatch({ type: 'start-submit' })
    const wxid = contact.ownerWxid
    const userIds = [contact.userId, ...[...choosed].map(id => allEmployees.get(id)!.userId)]
    void services.groups.create(wxid, userIds).then(res => {
      if (!res.success) void message.error(`群创建失败：${res.error}`)
    })
  }, [contact, choosed, allEmployees])

  return <main>
    <div styleName="content">
      <div styleName="employees">
        <div styleName="input">
          <Input value={search} onChange={searchOnChange} placeholder="搜索员工" />
        </div>
        <div styleName="list">
          {[...employees.values()].map(emp => {
            return <EmployeeItem
              key={emp.id}
              employee={emp}
              choosed={choosed.has(emp.id)}
              choose={contact.ownerWxid === emp.userId ? undefined : choose}
            />
          })}
        </div>
      </div>
      <div styleName="choosed">
        <section>
          <label>客户</label>
          <div>{contact.name}</div>
        </section>
        <section>
          <label>员工</label>
          <div styleName="list">
            {[...choosed]
              .map(id => allEmployees.get(id))
              .map(emp =>
                emp ? (
                  <ChoosedEmployeeItem
                    key={emp.id}
                    employee={emp}
                    choose={contact.ownerWxid === emp.userId ? undefined : choose}
                  />
                ) : null,
              )}
          </div>
        </section>
      </div>
    </div>
    <footer>
      <Button onClick={onCancel}>取消</Button>
      {choosed.size < 2 ? (
        <Tooltip title="建群必须选中2个或以上的员工">
          <Button disabled={true} type="primary">
            确定
          </Button>
        </Tooltip>
      ) : (
        <Button loading={submitting} type="primary" onClick={addGroup}>
          {submitting ? '创建中' : '确定'}
        </Button>
      )}
    </footer>
  </main>
}

function EmployeeItem(props: {
  employee: Contact
  choosed: boolean
  choose?: (id: string, choosed: boolean) => void // 不提供，代表这个人不能切换选择状态
}) {
  const { employee, choosed, choose } = props
  const onChange = useCallback(
    (e: CheckboxChangeEvent) => choose?.(employee.id, e.target.checked),
    [employee, choose],
  )
  return <Checkbox styleName="choose-item" checked={choosed} onChange={onChange} disabled={!choose}>
    <img loading="lazy" src={employee.avatar || defaultAvatar} />
    <span>{employee.name}</span>
  </Checkbox>
}

function ChoosedEmployeeItem(props: {
  employee: Contact
  choose?: (id: string, choosed: boolean) => void
}) {
  const { employee, choose } = props
  const remove = useCallback(() => choose?.(employee.id, false), [employee, choose])
  return <Tag styleName="item" closable={!!choose} onClose={remove}>
    <img loading="lazy" src={employee.avatar || defaultAvatar} />
    <span styleName="name">{employee.name}</span>
  </Tag>
}
